/*
 * @Author: LVGRAPE
 * @Date: 2022-12-08 11:51:12
 * @LastEditTime: 2025-03-14 11:54:55
 * @LastEditors: LVGRAPE
 * @Description:
 * @FilePath: \zino-fc-v4\ZINO\config\zino_config.c
 * 可以输入预定的版权声明、个性签名、空行等
 */
#include "zino_config.h"
#include "drv_flash.h"
#include "zino.h"
#include "board.h"
#include <string.h>

#include "maths.h"

#define DBG_TAG "config"
#define DBG_LVL DBG_ERROR
#include <rtdbg.h>

void zino_config_flash_erase()
{
    at32_flash_erase(CONFIG_START, CONFIG_SIZE);

}
typedef union
{
    struct {
        uint32_t flag : 8;
        uint32_t crc : 8;
        uint32_t total : 16;
    };
    uint32_t raw[1];
}ALIGN(4) zino_config_flag_t;
static zino_config_flag_t zino_config_flag;
void zino_config_save_all()
{
    /**
     * @brief
     * 0: flag
     * 1: crc
     * 2~3: data totallen
     * 4: data begin
     */

    zino_config_flash_erase();

    zino_config_flag.crc = ZINO_CONF_CRC_MAGICBEE;
    zino_config_flag.flag = ZINO_CONF_CRC_MAGICBEE;
    zino_config_flag.total = 0;
    uint32_t startAddr = CONFIG_START + 4;
    for (const zino_config_t* c = __zino_config_start;c < __zino_config_end;c++)
    {
        LOG_D("C:0x%08x id:%d verion:%d size:%d %08x\n", c, zinoConfigId(c), zinoConfigVersion(c), zinoConfigSize(c), c->address);
        // zino_config_flash_write(startAddr, c->address, zinoConfigSize(c));
        at32_flash_write(startAddr, c->address, zinoConfigSize(c));// write data to the memory space of the FLASH.
        zino_config_flag.crc = crc8_dvb_s2_update(zino_config_flag.crc, c->address, zinoConfigSize(c));
        startAddr += zinoConfigSize(c);
        zino_config_flag.total += zinoConfigSize(c);
        // for (uint8_t i = 0;i < zinoConfigSize(c);i++)
        // {
        //     // rt_kprintf("%d ", i);
        //     rt_kprintf("%02X ", (uint8_t)c->address[i]);
        // }
        // rt_kprintf("crc:%d\r\n", zino_config_flag.crc);
    }
    at32_flash_write(CONFIG_START, (uint8_t*)zino_config_flag.raw, sizeof(zino_config_flag.raw));
    LOG_I("Saved data: flag:%x crc:%x total:%dB \r\n", zino_config_flag.flag, zino_config_flag.crc, zino_config_flag.total);
}
int zino_config_reload()
{
    uint8_t crc = ZINO_CONF_CRC_MAGICBEE;
    uint32_t startAddr = CONFIG_START + 4;
    at32_flash_read(CONFIG_START, (uint8_t*)zino_config_flag.raw, sizeof(zino_config_flag.raw));
    if (zino_config_flag.flag != ZINO_CONF_CRC_MAGICBEE)
    {
        LOG_E("no saved date found!\r\n");
        return 1;
    }
    LOG_D("Checking crc...");
    for (startAddr = CONFIG_START + 4;startAddr < (CONFIG_START + 4 + zino_config_flag.total);startAddr++)
    {
        crc = crc8_dvb_s2(crc, *(uint8_t*)startAddr);
    }
    if (crc != zino_config_flag.crc)
    {
        LOG_E("crc check fail: save:0x%02X, crc:0x%02X\r\n ", zino_config_flag.crc, crc);
        return 2;
    }
    else
    {
        LOG_D("Crc ok!");
    }
    startAddr = CONFIG_START + 4;
    crc = ZINO_CONF_CRC_MAGICBEE;
    for (const zino_config_t* c = __zino_config_start;c < __zino_config_end;c++)
    {
        at32_flash_read(startAddr, c->address, zinoConfigSize(c));// read data from the memory space of the FLASH.
        crc = crc8_dvb_s2_update(crc, c->address, zinoConfigSize(c));
        startAddr += zinoConfigSize(c);
        // LOG_D("%p-C:%d id:%d verion:%d size:%d %08x \r\n", c, (int)zinoConfigIsValid(c), zinoConfigId(c), zinoConfigVersion(c), zinoConfigSize(c), c->address);
        // for (uint8_t i = 0;i < zinoConfigSize(c);i++)
        // {
        //     rt_kprintf("%02X ", (uint8_t)c->address[i]);
        // }
        // rt_kprintf("crc:%d\r\n", zino_config_flag.crc);
    }
    LOG_D("Read data from rom ok\n");

    return 0;
}
struct save_buff {
    uint8_t buff[24];
};

ZINO_CONFIG_REGISTER(struct save_buff, save_test, 0, 1);
ZINO_CONFIG_DECLARE(struct save_buff, save_test);
void save(int argc, char** argv)
{
    rt_memcpy(save_test()->buff, argv[1], rt_strlen(argv[1]));
    zino_config_save_all();
}
void save_test_read()
{
    rt_kprintf("save_test:%s\r\n", save_test()->buff);
}
ZINO_PREV_EXPORT(zino_config_reload);
// ZINO_APP_EXPORT(save_test_read);
MSH_CMD_EXPORT(save, save config);
